home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / ai / tierra40 / tierra / parse2.c < prev    next >
C/C++ Source or Header  |  1992-09-08  |  34KB  |  982 lines

  1. /* parse2.c   9-9-92  parser functions for instruction set 2 */
  2. /* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */
  3.  
  4. #if INST == 2
  5.  
  6. /* in INST == 2, the array of registers maps into the registers ax, bx, cx, dx
  7.    as follows:  c.re[0] = ax, c.re[1] = bx, c.re[2] = cx, c.re[3] = dx
  8.    but these can be reordered by the ax, bx, cx and dx instructions
  9.  
  10.     {0x00, "nop0", nop, pnop},
  11.     {0x01, "nop1", nop, pnop},
  12.     {0x02, "ax", regorder, pax},
  13.     {0x03, "bx", regorder, pbx},
  14.     {0x04, "cx", regorder, pcx},
  15.     {0x05, "dx", regorder, pdx},
  16.     {0x06, "movdd", movdd, pmovdd},
  17.     {0x07, "movdi", movdi, pmovdi},
  18.     {0x08, "movid", movid, pmovid},
  19.     {0x09, "movii", movii, pmovii},
  20.     {0x0a, "push", push, ppush},
  21.     {0x0b, "pop", pop, ppop},
  22.     {0x0c, "put", put, pput},
  23.     {0x0d, "get", get, pget},
  24.     {0x0e, "inc", math, pinc},
  25.     {0x0f, "dec", math, pdec},
  26.     {0x10, "add", math, padd},
  27.     {0x11, "sub", math, psub},
  28.     {0x12, "zero", movdd, pzero},
  29.     {0x13, "shl", shl, pshl},
  30.     {0x14, "not0", not0, pnot0},
  31.     {0x15, "not", not, pnot},
  32.     {0x16, "ifz", ifz, pifz},
  33.     {0x17, "iffl", ifz, piffl},
  34.     {0x18, "jmp", adr, ptjmp},
  35.     {0x19, "jmpb", adr, ptjmpb},
  36.     {0x1a, "call", tcall, ptcall},
  37.     {0x1b, "adr", adr, padr},
  38.     {0x1c, "adrb", adr, padrb},
  39.     {0x1d, "adrf", adr, padrf},
  40.     {0x1e, "mal", malchm, pmal},
  41.     {0x1f, "divide", divide, pdivide}
  42. */
  43.  
  44. void pnop(ce) /* do nothing */
  45. Pcells  ce;
  46. {   is.iip = is.dib = 1; }
  47.  
  48. /* void regorder(ce) pushst(ce); is.sval += flaw(ce);
  49.  * is.sval  = the number of the register that will go to the top
  50.  */
  51. void pax(ce)
  52. Pcells  ce;
  53. {   is.iip = is.dib = 1;
  54.     if (is.eins->exec)
  55.         return ;
  56.     is.sval = 0;
  57. }
  58.  
  59. /* void regorder(ce) pushst(ce); is.sval += flaw(ce);
  60.  * is.sval  = the number of the register that will go to the top
  61.  */
  62. void pbx(ce)
  63. Pcells  ce;
  64. {   is.iip = is.dib = 1;
  65.     if (is.eins->exec)
  66.         return ;
  67.     is.sval = 1;
  68. }
  69.  
  70. /* void regorder(ce) pushst(ce); is.sval += flaw(ce);
  71.  * is.sval  = the number of the register that will go to the top
  72.  */
  73. void pcx(ce)
  74. Pcells  ce;
  75. {   is.iip = is.dib = 1;
  76.     if (is.eins->exec)
  77.         return ;
  78.     is.sval = 2;
  79. }
  80.  
  81. /* void regorder(ce) pushst(ce); is.sval += flaw(ce);
  82.  * is.sval  = the number of the register that will go to the top
  83.  */
  84. void pdx(ce)
  85. Pcells  ce;
  86. {   is.iip = is.dib = 1;
  87.     if (is.eins->exec)
  88.         return ;
  89.     is.sval = 3;
  90. }
  91.  
  92. /* void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  93.  * is.dreg = destination register, where moved value will be placed
  94.  * is.sval = value to be placed in the dest reg
  95.  * is.dmod = value by which to modulus destination register
  96.  * is.dran = range within which to contain destination register
  97.  */
  98. void pmovdd(ce) /* R0 = R1 */
  99. Pcells  ce;
  100. {   I32s  tval;
  101.  
  102.     is.iip = is.dib = 1;
  103.     if (is.eins->exec)
  104.         return ;
  105.     tval = ce->c.re[NUMREG] + flaw(ce);
  106.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  107.     tval = ce->c.re[NUMREG+1] + flaw(ce);
  108.     is.sval = ce->c.re[mo(tval, NUMREG)];
  109.     is.dran = SoupSize;
  110. }
  111.  
  112. /* void movdi(ce) is.dins->inst = is.sval + flaw(ce);
  113.  * is.dval  = address of destination instruction
  114.  * is.dins  = pointer to destination instruction
  115.  * is.sval  = value to be moved to destination instruction
  116.  * is.sval2 = original value of destination instruction
  117.  */
  118. void pmovdi(ce) /* soup [R0] = R1 */
  119. Pcells  ce;
  120. {   I32s  tval;
  121.  
  122.     is.iip = is.dib = 1;
  123.     if (is.eins->exec)
  124.         return ;
  125.     tval = ce->c.re[NUMREG] + flaw(ce);
  126.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  127.     is.dval = ad(tval);
  128.     tval = ce->c.re[NUMREG+1] + flaw(ce);
  129.     is.sval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  130. #if PLOIDY == 1
  131.     is.dins = &soup[is.dval];
  132. #else /* PLOIDY > 1 */
  133.     is.dins = &soup[is.dval][ce->d.tr];
  134. #endif /* PLOIDY > 1 */
  135.     is.sval2 = is.dins->inst;
  136. }
  137.  
  138. /* void movid(ce) *(is.dreg) = is.sins->inst + flaw(ce);
  139.  * is.sins = pointer to source instruction
  140.  * is.sval = address of source instruction
  141.  * is.dreg = destination register, where moved value will be placed
  142.  * is.dmod = value by which to modulus destination register
  143.  * is.dran = range within which to contain destination register
  144.  */
  145. void pmovid(ce) /* R0 = soup [R1] */
  146. Pcells  ce;
  147. {   I32s  tval;
  148.  
  149.     is.iip = is.dib = 1;
  150.     if (is.eins->exec)
  151.         return ;
  152.     tval = ce->c.re[NUMREG] + flaw(ce);
  153.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  154.     tval = ce->c.re[NUMREG+1] + flaw(ce);
  155.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  156.     is.sval = ad(tval);
  157. #if PLOIDY == 1
  158.     is.sins = &soup[is.sval];
  159. #else /* PLOIDY > 1 */
  160.     is.sins = &soup[is.sval][ce->d.tr];
  161. #endif /* PLOIDY > 1 */
  162.     is.dran = SoupSize;
  163. }
  164.  
  165. /* void movii(ce) is.dins->inst = is.sins->inst;
  166.  * is.dval  = address of destination instruction
  167.  * is.sval  = address of source instruction
  168.  * is.dins  = pointer to destination instruction
  169.  * is.sins  = pointer to source instruction
  170.  * is.dtra  = track of destination instruction
  171.  * is.sval2 = original value of destination instruction
  172.  */
  173. void pmovii(ce)
  174. Pcells  ce;
  175. {   I32s  tval;
  176.  
  177.     is.iip = is.dib = 1;
  178.     if (is.eins->exec)
  179.         return ;
  180.     tval = ce->c.re[NUMREG] + flaw(ce);
  181.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  182.     is.dval = ad(tval);
  183.     tval = ce->c.re[NUMREG+1] + flaw(ce);
  184.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  185.     is.sval = ad(tval);
  186. #if PLOIDY == 1
  187.     is.dins = &soup[is.dval];
  188.     is.sins = &soup[is.sval];
  189. #else /* PLOIDY > 1 */
  190.     is.dins = &soup[is.dval][ce->d.tr];
  191.     is.sins = &soup[is.sval][ce->d.tr];
  192. #endif /* PLOIDY > 1 */
  193.     is.dtra = ce->d.tr;
  194.     is.sval2 = is.dins->inst;
  195. #ifdef HSEX
  196.     if (ce->d.x_over_addr)
  197.     {   if ((!ce->d.mov_daught) && (!FindMate(ce)))
  198.             ce->d.x_over_addr = ce->d.mate_addr = 0;
  199.         else UseMate(ce);
  200.     }
  201. #endif
  202. }
  203.  
  204. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  205.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  206.  * is.sval = value to be pushed onto the stack
  207.  */
  208. void ppush(ce) /* push R0 onto stack */
  209. Pcells  ce;
  210. {   I32s  tval;
  211.  
  212.     is.iip = is.dib = 1;
  213.     if (is.eins->exec)
  214.         return ;
  215.     tval = ce->c.re[NUMREG] + flaw(ce);
  216.     is.sval = ce->c.re[mo(tval, NUMREG)];
  217. }
  218.  
  219. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  220.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  221.  * is.dreg = destination register, where value popped off stack will go
  222.  * is.dmod = value by which to modulus destination register
  223.  * is.dran = range within which to contain destination register
  224.  */
  225. void ppop(ce) /* pop R0 off of stack */
  226. Pcells  ce;
  227. {   I32s  tval;
  228.  
  229.     is.iip = is.dib = 1;
  230.     if (is.eins->exec)
  231.         return ;
  232.     tval = ce->c.re[NUMREG] + flaw(ce);
  233.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  234.     is.dran = SoupSize;
  235. }
  236.  
  237. /* void put(ce) write a value to the output buffer
  238.  * ce->c.pb[PUTBUFSIZ]     == pointer to next output value to be written
  239.  * ce->c.pb[PUTBUFSIZ + 1] == pointer to next output value to be read
  240.  * ce->c.pb[PUTBUFSIZ + 2] == number of unread output values
  241.  *
  242.  * is.dcel  = destination cell, in whose buffer the value will be put
  243.  * is.dreg  = destination "register" in the put buffer
  244.  * is.dval3 = destination for address returned by adr()
  245.  * is.mode3 = #ifdef ICC:  0 = broadcast to other cells' get buffer
  246.  *                         1 = write to other cell's get buffer
  247.  *            #ifndef ICC: write to own put buffer (prayer)
  248.  * is.sval  = value to be placed in the dest reg
  249.  *
  250.  * #ifndef ICC specify the values used by movdd():
  251.  * is.dreg = destination register, where moved value will be placed
  252.  * is.sval = value to be placed in the dest reg
  253.  * is.dmod = value by which to modulus destination register
  254.  * is.dran = range within which to contain destination register
  255.  *
  256.  * #ifdef ICC specify the values used by adr():
  257.  * void adr(ce) find address of a template
  258.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  259.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  260.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  261.  * is.dval  = starting address for forward search
  262.  * is.dval2 = starting address for backward search
  263.  * is.dreg  = destination register where target address will be stored
  264.  * is.dreg2 = destination register where template size will be stored
  265.  * is.dreg3 = destination register where offset of target will be stored
  266.  * is.sval  = return address if template size = 0
  267.  * is.sval2 = template size, 0 = no template
  268.  * is.sval3 = search limit, and return for distance actually searched
  269.  * is.dmod  = modulus value for is.dreg
  270.  * is.dmod2 = modulus value for is.dreg2
  271.  * is.dmod3 = modulus value for is.dreg3
  272.  * is.dran  = range to maintain for is.dreg
  273.  * is.dran2 = range to maintain for is.dreg2
  274.  * is.dran3 = range to maintain for is.dreg3
  275.  */
  276. void pput(ce) /* write R0 to output port; or if put template, put to input */
  277. Pcells  ce;   /* port of creature(s) with complementary get template */
  278. {   I32s    a, s = 0, adre, tval;
  279.     Pcells  dc;
  280.     I8s     md;
  281.  
  282.     is.iip = is.dib = 1;
  283.     if (is.eins->exec)
  284.         return ;
  285. #ifdef ICC
  286.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  287.     while(1) /* find size of template, s = size */
  288.     {
  289. #if PLOIDY == 1
  290.         if(soup[ad(a + s)].inst != Nop0 &&
  291.            soup[ad(a + s)].inst != Nop1)
  292. #else /* PLOIDY > 1 */
  293.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  294.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  295. #endif /* PLOIDY > 1 */
  296.             break;
  297.         s++;
  298.     }
  299.     tval = ce->c.re[NUMREG] + flaw(ce);
  300.     is.sval = ce->c.re[mo(tval, NUMREG)];
  301.     if (s)
  302.     {   is.dreg  = &is.dval3;  /* dest register for address */
  303.         is.dreg2 = &BitBucket; /* dest reg for template size */
  304.         is.dreg3 = &BitBucket; /* dest reg for offset */
  305.         is.sval2 = s;
  306.         is.sval3 = Put_limit;
  307.         is.dval  = ce->mm.p + ce->mm.s;
  308.         is.dval2 = ce->mm.p - 1;
  309.         is.mode  = 0;
  310.         is.mode2 = 1;
  311.         is.mode3 = 0;
  312.         is.iip   = s + 1;
  313.     }
  314.     else
  315.     {   tval = ce->c.re[NUMREG+1] + flaw(ce);
  316.         tval = ce->c.re[mo(tval, NUMREG)];
  317.         tval = ad(tval);
  318.         if (!IsFree(tval))
  319.             WhichCell(tval, &is.dcel, &md);
  320.         else
  321.             is.dreg = &BitBucket;
  322.         is.mode3 = 1;
  323.     }
  324. #else  /* ICC */
  325.     tval = ce->c.re[NUMREG] + flaw(ce);
  326.     is.sval = ce->c.re[mo(tval, NUMREG)];
  327.     is.dreg = &ce->c.pb[ce->c.pb[PUTBUFSIZ]];
  328. #endif /* ICC */
  329. }
  330.  
  331. /* void get(ce) *(is.dreg) = is.sval + flaw(ce);
  332.  * ce->c.gb[GETBUFSIZ]     == pointer to next input value to be read
  333.  * ce->c.gb[GETBUFSIZ + 1] == pointer to next input value to be written
  334.  * ce->c.gb[GETBUFSIZ + 2] == number of unread input values
  335.  *
  336.  * specify the values used by movdd():
  337.  * void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  338.  * is.dreg = destination register, where moved value will be placed
  339.  * is.sval = value to be placed in the dest reg
  340.  * is.dmod = value by which to modulus destination register
  341.  * is.dran = range within which to contain destination register
  342.  */
  343. void pget(ce) /* read from input port into R0 */
  344. Pcells  ce;
  345. {   I32s    a, tval;
  346.  
  347.     is.iip = is.dib = 1;
  348.     if (is.eins->exec)
  349.         return ;
  350.     tval = ce->c.re[NUMREG] + flaw(ce);
  351.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  352.     is.sval = ce->c.gb[ce->c.gb[GETBUFSIZ]];
  353.     is.dran = SoupSize;
  354.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  355.     while(1) /* find size of template, s = size */
  356.     {
  357. #if PLOIDY == 1
  358.         if(soup[ad(a)].inst != Nop0 &&
  359.            soup[ad(a)].inst != Nop1)
  360. #else /* PLOIDY > 1 */
  361.         if(soup[ad(a)][ce->d.tr].inst != Nop0 &&
  362.            soup[ad(a)][ce->d.tr].inst != Nop1)
  363. #endif /* PLOIDY > 1 */
  364.             break;
  365.         a++; is.iip++;
  366.     }
  367. }
  368.  
  369. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  370.  * is.dreg  = destination register, where calculation will be stored
  371.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  372.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  373.  * is.dmod  = value by which to modulus destination register
  374.  * is.dran  = range within which to contain destination register
  375.  */
  376. void pinc(ce) /* R0++ */
  377. Pcells  ce;
  378. {   I32s  tval;
  379.  
  380.     is.iip = is.dib = 1;
  381.     if (is.eins->exec)
  382.         return ;
  383.     tval = ce->c.re[NUMREG] + flaw(ce);
  384.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  385.     tval = ce->c.re[NUMREG] + flaw(ce);
  386.     is.sval = ce->c.re[mo(tval, NUMREG)];
  387.     is.sval2 = 1;
  388.     is.dran = SoupSize;
  389. }
  390.  
  391. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  392.  * is.dreg  = destination register, where calculation will be stored
  393.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  394.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  395.  * is.dmod  = value by which to modulus destination register
  396.  * is.dran  = range within which to contain destination register
  397.  */
  398. void pdec(ce) /* R0-- */
  399. Pcells  ce;
  400. {   I32s  tval;
  401.  
  402.     is.iip = is.dib = 1;
  403.     if (is.eins->exec)
  404.         return ;
  405.     tval = ce->c.re[NUMREG] + flaw(ce);
  406.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  407.     tval = ce->c.re[NUMREG] + flaw(ce);
  408.     is.sval = ce->c.re[mo(tval, NUMREG)];
  409.     is.sval2 = -1;
  410.     is.dran = SoupSize;
  411. }
  412.  
  413. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  414.  * is.dreg  = destination register, where calculation will be stored
  415.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  416.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  417.  * is.dmod  = value by which to modulus destination register
  418.  * is.dran  = range within which to contain destination register
  419.  */
  420. void padd(ce) /* R2 = R1 + R0 */
  421. Pcells  ce;
  422. {   I32s  tval;
  423.  
  424.     is.iip = is.dib = 1;
  425.     if (is.eins->exec)
  426.         return ;
  427.     tval = ce->c.re[NUMREG+2] + flaw(ce);
  428.     is.dreg  = &(ce->c.re[mo(tval, NUMREG)]);
  429.     tval = ce->c.re[NUMREG+1] + flaw(ce);
  430.     is.sval  = ce->c.re[mo(tval, NUMREG)];
  431.     tval = ce->c.re[NUMREG] + flaw(ce);
  432.     is.sval2 = ce->c.re[mo(tval, NUMREG)];
  433.     is.dran = SoupSize;
  434. }
  435.  
  436. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  437.  * is.dreg  = destination register, where calculation will be stored
  438.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  439.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  440.  * is.dmod  = value by which to modulus destination register
  441.  * is.dran  = range within which to contain destination register
  442.  */
  443. void psub(ce) /* R2 = R1 - R0 */
  444. Pcells  ce;
  445. {   I32s  tval;
  446.  
  447.     is.iip = is.dib = 1;
  448.     if (is.eins->exec)
  449.         return ;
  450.     tval = ce->c.re[NUMREG+2] + flaw(ce);
  451.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  452.     tval = ce->c.re[NUMREG+1] + flaw(ce);
  453.     is.sval  =  ce->c.re[mo(tval, NUMREG)];
  454.     tval = ce->c.re[NUMREG+0] + flaw(ce);
  455.     is.sval2 = -ce->c.re[mo(tval, NUMREG)];
  456.     is.dran = SoupSize;
  457. }
  458.  
  459. /* void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  460.  * is.dreg = destination register, where moved value will be placed
  461.  * is.sval = value to be placed in the dest reg
  462.  * is.dmod = value by which to modulus destination register
  463.  * is.dran = range within which to contain destination register
  464.  */
  465. void pzero(ce) /* R0 = 0 */
  466. Pcells  ce;
  467. {   I32s  tval;
  468.  
  469.     is.iip = is.dib = 1;
  470.     if (is.eins->exec)
  471.         return ;
  472.     tval = ce->c.re[NUMREG] + flaw(ce);
  473.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  474.     is.sval = 0;
  475. }
  476.  
  477. /* void not0(ce) *(is.dreg) ^= (1 + flaw(ce));
  478.  * is.dreg = destination register, whose bit will be flipped
  479.  * is.dmod = value by which to modulus destination register
  480.  * is.dran = range within which to contain destination register
  481.  */
  482. void pnot0(ce) /* flip low order bit of R0 */
  483. Pcells  ce;
  484. {   I32s  tval;
  485.  
  486.     is.iip = is.dib = 1;
  487.     if (is.eins->exec)
  488.         return ;
  489.     tval = ce->c.re[NUMREG] + flaw(ce);
  490.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  491.     is.dran = SoupSize;
  492. }
  493.  
  494. /* void shl(ce) *(is.dreg) <<= (Reg) (1 + flaw(ce));
  495.  * is.dreg = destination register, whose bits will be shifted left
  496.  * is.dmod = value by which to modulus destination register
  497.  * is.dran = range within which to contain destination register
  498.  */
  499. void pshl(ce) /* shift left all bits of R0 */
  500. Pcells  ce;
  501. {   I32s  tval;
  502.  
  503.     is.iip = is.dib = 1;
  504.     if (is.eins->exec)
  505.         return ;
  506.     tval = ce->c.re[NUMREG] + flaw(ce);
  507.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  508.     is.dran = SoupSize;
  509. }
  510.  
  511. /* void not(ce) *(is.dreg) = ~(is.sval) + flaw(ce);
  512.  * is.dreg = destination register
  513.  * is.sval = value whose bits will be flipped and put in dest reg
  514.  * is.dmod = value by which to modulus destination register
  515.  * is.dran = range within which to contain destination register
  516.  */
  517. void pnot(ce) /* flip all bits of R0 */
  518. Pcells  ce;
  519. {   I32s  tval;
  520.  
  521.     is.iip = is.dib = 1;
  522.     if (is.eins->exec)
  523.         return ;
  524.     tval = ce->c.re[NUMREG] + flaw(ce);
  525.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  526.     is.dran = SoupSize;
  527. }
  528.  
  529. /* void ifz(ce) if (is.sval + flaw(ce)) is.iip = is.sval2;
  530.  * is.sval  = value to test for zero
  531.  * is.sval2 = amount to increment IP if is.sval == 0
  532.  * is.iip   = amount to increment IP if is.sval != 0
  533.  */
  534. void pifz(ce) /* execute next instruction, if R0 == 0 */
  535. Pcells  ce;
  536. {   I32s  tval;
  537.  
  538.     is.iip = is.dib = 1;
  539.     if (is.eins->exec)
  540.         return ;
  541.     tval = ce->c.re[NUMREG] + flaw(ce);
  542.     is.sval = ce->c.re[mo(tval, NUMREG)];
  543.     is.sval2 = 2;
  544. }
  545.  
  546. /* void ifz(ce) if (is.sval + flaw(ce)) is.iip = is.sval2;
  547.  * is.sval  = value to test for zero
  548.  * is.sval2 = amount to increment IP if is.sval == 0
  549.  * is.iip   = amount to increment IP if is.sval != 0
  550.  */
  551. void piffl(ce) /* skip next instruction, if flag == 0 */
  552. Pcells  ce;
  553. {   is.iip = is.dib = 1;
  554.     if (is.eins->exec)
  555.         return ;
  556.     is.sval = ce->c.fl;
  557.     is.sval2 = 1;
  558.     is.iip = 2;
  559.     is.dib = 1;
  560. }
  561.  
  562. /* void adr(ce) find address of a template
  563.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  564.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  565.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  566.  * is.dval  = starting address for forward search
  567.  * is.dval2 = starting address for backward search
  568.  * is.dreg  = destination register where target address will be stored
  569.  * is.dreg2 = destination register where template size will be stored
  570.  * is.dreg3 = destination register where offset of target will be stored
  571.  * is.sval  = return address if template size = 0
  572.  * is.sval2 = template size, 0 = no template
  573.  * is.sval3 = search limit, and return for distance actually searched
  574.  * is.dmod  = modulus value for is.dreg
  575.  * is.dmod2 = modulus value for is.dreg2
  576.  * is.dmod3 = modulus value for is.dreg3
  577.  * is.dran  = range to maintain for is.dreg
  578.  * is.dran2 = range to maintain for is.dreg2
  579.  * is.dran3 = range to maintain for is.dreg3
  580.  */
  581. void ptjmp(ce) /* outward template jump */
  582. Pcells  ce;
  583. {   I32s    a, s = 0, tval;
  584.  
  585.     is.iip = is.dib = 1;
  586.     if (is.eins->exec)
  587.         return ;
  588.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  589.     while(1) /* find size of template, s = size */
  590.     {   
  591. #if PLOIDY == 1
  592.         if(soup[ad(a + s)].inst != Nop0 &&
  593.            soup[ad(a + s)].inst != Nop1)
  594. #else /* PLOIDY > 1 */
  595.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  596.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  597. #endif /* PLOIDY > 1 */
  598.             break;
  599.         s++;
  600.     }
  601.     is.dreg  = &(ce->c.ip); /* destination register for address */
  602.     is.dreg2 = &BitBucket; /* destination register for template size */
  603.     is.dreg3 = &BitBucket; /* dest reg for offset */
  604.     tval = ce->c.re[NUMREG] + flaw(ce);
  605.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  606.     is.sval  = ad(tval); /* target for IP if s == 0 */
  607.     is.sval2 = s;  /* size of template */
  608.     is.sval3 = Search_limit;
  609.     is.dmod  = SoupSize;
  610.     is.dval  = ad(a + s + 1); /* start address for forward search */
  611.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  612.     is.mode  = 0; /* outward jump */
  613.     is.mode2 = 1;
  614.     is.dib = 1;
  615.     is.iip = 0;
  616. }
  617.  
  618. /* void adr(ce) find address of a template
  619.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  620.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  621.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  622.  * is.dval  = starting address for forward search
  623.  * is.dval2 = starting address for backward search
  624.  * is.dreg  = destination register where target address will be stored
  625.  * is.dreg2 = destination register where template size will be stored
  626.  * is.dreg3 = destination register where offset of target will be stored
  627.  * is.sval  = return address if template size = 0
  628.  * is.sval2 = template size, 0 = no template
  629.  * is.sval3 = search limit, and return for distance actually searched
  630.  * is.dmod  = modulus value for is.dreg
  631.  * is.dmod2 = modulus value for is.dreg2
  632.  * is.dmod3 = modulus value for is.dreg3
  633.  * is.dran  = range to maintain for is.dreg
  634.  * is.dran2 = range to maintain for is.dreg2
  635.  * is.dran3 = range to maintain for is.dreg3
  636.  */
  637. void ptjmpb(ce) /* backward template jump */
  638. Pcells  ce;
  639. {   I32s    a, s = 0, tval;
  640.  
  641.     is.iip = is.dib = 1;
  642.     if (is.eins->exec)
  643.         return ;
  644.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  645.     while(1) /* find size of template, s = size */
  646.     {   
  647. #if PLOIDY == 1
  648.         if(soup[ad(a + s)].inst != Nop0 &&
  649.            soup[ad(a + s)].inst != Nop1)
  650. #else /* PLOIDY > 1 */
  651.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  652.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  653. #endif /* PLOIDY > 1 */
  654.             break;
  655.         s++;
  656.     }
  657.     is.dreg  = &(ce->c.ip); /* destination register for address */
  658.     is.dreg2 = &BitBucket; /* destination register for template size */
  659.     is.dreg3 = &BitBucket; /* dest reg for offset */
  660.     tval = ce->c.re[NUMREG] + flaw(ce);
  661.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  662.     is.sval  = ad(tval); /* target for IP if s == 0 */
  663.     is.sval2 = s;  /* size of template */
  664.     is.sval3 = Search_limit;
  665.     is.dmod  = SoupSize;
  666.     is.dval  = ad(a + s + 1); /* start address for forward search */
  667.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  668.     is.mode  = 2; /* backward jump */
  669.     is.mode2 = 2;
  670.     is.dib = 1;
  671.     is.iip = 0;
  672. }
  673.  
  674. /* void tcall(ce) adr(ce); push(ce); */
  675. /* void adr(ce) find address of a template
  676.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  677.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  678.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  679.  * is.dval  = starting address for forward search
  680.  * is.dval2 = starting address for backward search
  681.  * is.dreg  = destination register where target address will be stored
  682.  * is.dreg2 = destination register where template size will be stored
  683.  * is.dreg3 = destination register where offset of target will be stored
  684.  * is.sval  = return address if template size = 0
  685.  * is.sval2 = template size, 0 = no template
  686.  * is.sval3 = search limit, and return for distance actually searched
  687.  * is.dmod  = modulus value for is.dreg
  688.  * is.dmod2 = modulus value for is.dreg2
  689.  * is.dmod3 = modulus value for is.dreg3
  690.  * is.dran  = range to maintain for is.dreg
  691.  * is.dran2 = range to maintain for is.dreg2
  692.  * is.dran3 = range to maintain for is.dreg3
  693.  */
  694. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  695.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  696.  * is.sval = value to be pushed onto the stack
  697.  */
  698. void ptcall(ce) /* push ip to stack, outward template jump */
  699. Pcells  ce;
  700. {   I32s    a, s = 0;
  701.  
  702.     is.iip = is.dib = 1;
  703.     if (is.eins->exec)
  704.         return ;
  705.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  706.     while(1) /* find size of template, s = size */
  707.     {
  708. #if PLOIDY == 1
  709.         if(soup[ad(a + s)].inst != Nop0 &&
  710.            soup[ad(a + s)].inst != Nop1)
  711. #else /* PLOIDY > 1 */
  712.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  713.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  714. #endif /* PLOIDY > 1 */
  715.             break;
  716.         s++;
  717.     }
  718.     is.dreg  = &(ce->c.ip); /* destination register for address */
  719.     is.dreg2 = &BitBucket; /* destination register for template size */
  720.     is.dreg3 = &BitBucket; /* destination register for offset */
  721.     is.sval  = ad(ce->c.ip + s + 1); /* address to be pushed onto stack */
  722.     is.sval2 = s;  /* size of template */
  723.     is.sval3 = Search_limit;
  724.     is.dmod  = SoupSize;
  725.     is.dval  = ad(a + s + 1); /* start address for forward search */
  726.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  727.     is.mode  = 0; /* outward jump */
  728.     is.mode2 = 1;
  729.     is.dib = 1;
  730.     is.iip = 0;
  731. }
  732.  
  733. /* void adr(ce) find address of a template
  734.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  735.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  736.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  737.  * is.dval  = starting address for forward search
  738.  * is.dval2 = starting address for backward search
  739.  * is.dreg  = destination register where target address will be stored
  740.  * is.dreg2 = destination register where template size will be stored
  741.  * is.dreg3 = destination register where offset of target will be stored
  742.  * is.sval  = return address if template size = 0
  743.  * is.sval2 = template size, 0 = no template
  744.  * is.sval3 = search limit, and return for distance actually searched
  745.  * is.dmod  = modulus value for is.dreg
  746.  * is.dmod2 = modulus value for is.dreg2
  747.  * is.dmod3 = modulus value for is.dreg3
  748.  * is.dran  = range to maintain for is.dreg
  749.  * is.dran2 = range to maintain for is.dreg2
  750.  * is.dran3 = range to maintain for is.dreg3
  751.  */
  752. /* search outward for template, put address in R0, template size in R1,
  753.    and offset in R0, start search at offset +- R0
  754. */
  755. void padr(ce)
  756. Pcells  ce;
  757. {   I32s    a, s = 0, tval;
  758.  
  759.     is.iip = is.dib = 1;
  760.     if (is.eins->exec)
  761.         return ;
  762.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  763.     while(1) /* find size of template, s = size */
  764.     {
  765. #if PLOIDY == 1
  766.         if(soup[ad(a + s)].inst != Nop0 &&
  767.            soup[ad(a + s)].inst != Nop1)
  768. #else /* PLOIDY > 1 */
  769.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  770.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  771. #endif /* PLOIDY > 1 */
  772.             break;
  773.         s++;
  774.     }
  775.     if (s)
  776.     {   tval = ce->c.re[NUMREG] + flaw(ce);
  777.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  778.         tval = ce->c.re[NUMREG+1] + flaw(ce);
  779.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  780.         tval = ce->c.re[NUMREG+2] + flaw(ce);
  781.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  782.     }
  783.     else
  784.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  785.     is.sval2 = s;  /* size of template */
  786.     is.dmod  = SoupSize;
  787.     is.dran2 = SoupSize;
  788.     is.dmod3 = SoupSize;
  789.     tval = ce->c.re[NUMREG] + flaw(ce);
  790.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  791.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  792.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  793.     is.sval3 = Search_limit - tval;
  794.     is.mode  = 0; /* outward search */
  795.     is.mode2 = 1;
  796.     is.iip = s + 1; is.dib = 1;
  797. }
  798.  
  799. /* void adr(ce) find address of a template
  800.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  801.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  802.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  803.  * is.dval  = starting address for forward search
  804.  * is.dval2 = starting address for backward search
  805.  * is.dreg  = destination register where target address will be stored
  806.  * is.dreg2 = destination register where template size will be stored
  807.  * is.dreg3 = destination register where offset of target will be stored
  808.  * is.sval  = return address if template size = 0
  809.  * is.sval2 = template size, 0 = no template
  810.  * is.sval3 = search limit, and return for distance actually searched
  811.  * is.dmod  = modulus value for is.dreg
  812.  * is.dmod2 = modulus value for is.dreg2
  813.  * is.dmod3 = modulus value for is.dreg3
  814.  * is.dran  = range to maintain for is.dreg
  815.  * is.dran2 = range to maintain for is.dreg2
  816.  * is.dran3 = range to maintain for is.dreg3
  817.  */
  818. /* search backward for template, put address in R0, template size in R1,
  819.    and offset in R0, start search at offset - R0
  820. */
  821. void padrb(ce)
  822. Pcells  ce;
  823. {   I32s    a, s = 0, tval;
  824.  
  825.     is.iip = is.dib = 1;
  826.     if (is.eins->exec)
  827.         return ;
  828.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  829.     while(1) /* find size of template, s = size */
  830.     {
  831. #if PLOIDY == 1
  832.         if(soup[ad(a + s)].inst != Nop0 &&
  833.            soup[ad(a + s)].inst != Nop1)
  834. #else /* PLOIDY > 1 */
  835.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  836.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  837. #endif /* PLOIDY > 1 */
  838.             break;
  839.         s++;
  840.     }
  841.     if (s)
  842.     {   tval = ce->c.re[NUMREG] + flaw(ce);
  843.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  844.         tval = ce->c.re[NUMREG+1] + flaw(ce);
  845.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  846.         tval = ce->c.re[NUMREG+2] + flaw(ce);
  847.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  848.     }
  849.     else
  850.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  851.     is.sval2 = s;  /* size of template */
  852.     is.dmod  = SoupSize;
  853.     is.dran2 = SoupSize;
  854.     is.dmod3 = SoupSize;
  855.     tval = ce->c.re[NUMREG] + flaw(ce);
  856.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  857.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  858.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  859.     is.sval3 = Search_limit - tval;
  860.     is.mode  = 2; /* backward search */
  861.     is.mode2 = 2;
  862.     is.iip = s + 1; is.dib = 1;
  863. }
  864.  
  865. /* void adr(ce) find address of a template
  866.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  867.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  868.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  869.  * is.dval  = starting address for forward search
  870.  * is.dval2 = starting address for backward search
  871.  * is.dreg  = destination register where target address will be stored
  872.  * is.dreg2 = destination register where template size will be stored
  873.  * is.dreg3 = destination register where offset of target will be stored
  874.  * is.sval  = return address if template size = 0
  875.  * is.sval2 = template size, 0 = no template
  876.  * is.sval3 = search limit, and return for distance actually searched
  877.  * is.dmod  = modulus value for is.dreg
  878.  * is.dmod2 = modulus value for is.dreg2
  879.  * is.dmod3 = modulus value for is.dreg3
  880.  * is.dran  = range to maintain for is.dreg
  881.  * is.dran2 = range to maintain for is.dreg2
  882.  * is.dran3 = range to maintain for is.dreg3
  883.  */
  884. /* search forward for template, put address in R0, template size in R1,
  885.    and offset in R0, start search at offset + R0
  886.  */
  887. void padrf(ce)
  888. Pcells  ce;
  889. {   I32s    a, s = 0, tval;
  890.  
  891.     is.iip = is.dib = 1;
  892.     if (is.eins->exec)
  893.         return ;
  894.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  895.     while(1) /* find size of template, s = size */
  896.     {
  897. #if PLOIDY == 1
  898.         if(soup[ad(a + s)].inst != Nop0 &&
  899.            soup[ad(a + s)].inst != Nop1)
  900. #else /* PLOIDY > 1 */
  901.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  902.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  903. #endif /* PLOIDY > 1 */
  904.             break;
  905.         s++;
  906.     }
  907.     if (s)
  908.     {   tval = ce->c.re[NUMREG] + flaw(ce);
  909.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  910.         tval = ce->c.re[NUMREG+1] + flaw(ce);
  911.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  912.         tval = ce->c.re[NUMREG+2] + flaw(ce);
  913.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  914.     }
  915.     else
  916.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  917.     is.sval2 = s;  /* size of template */
  918.     is.dmod  = SoupSize;
  919.     is.dran2 = SoupSize;
  920.     is.dmod3 = SoupSize;
  921.     tval = ce->c.re[NUMREG] + flaw(ce);
  922.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  923.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  924.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  925.     is.sval3 = Search_limit - tval;
  926.     is.mode  = 1; /* forward search */
  927.     is.mode2 = 1;
  928.     is.iip = s + 1; is.dib = 1;
  929. }
  930.  
  931. /* void malchm(ce) is.sval2 = mal(ce,&is.sval3,is.sval,is.mode2);
  932.  *                 *(is.dreg) = is.sval3;
  933.  *                 chmode(ce,is.sval3,is.sval2,is.mode);
  934.  * is.dreg  = destination register where allocated address is stored
  935.  * is.sval  = requested size of block for mal()
  936.  * is.sval2 = flawed size of block (assigned in instruct.c)
  937.  * is.sval3 = suggested address, and allocated address
  938.  * is.mode  = memory protection mode (rwx), probably MemModeProt
  939.  * is.mode2 = memory allocation mode for mal()
  940.  */
  941. void pmal(ce)  /* allocate space for a new cell */
  942. Pcells  ce;
  943. {   I32s  tval;
  944.  
  945.     is.iip = is.dib = 1;
  946.     if (is.eins->exec)
  947.         return ;
  948.     tval = ce->c.re[NUMREG] + flaw(ce);
  949.     is.dreg  = &(ce->c.re[mo(tval, NUMREG)]);
  950.     tval = ce->c.re[NUMREG] + flaw(ce);
  951.     is.sval  = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  952.     tval = ce->c.re[NUMREG + 1] + flaw(ce);
  953.     is.sval3 = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  954.     if (is.sval3 < 0)
  955.         is.mode2 = 1; /* better fit */
  956.     else
  957.         is.mode2 = 6; /* suggester address (is.sval3) */
  958.     is.mode = MemModeProt; /* only write privelage works at the moment */
  959. }
  960.  
  961. /* void divide(ce) cell division
  962.  * is.mode  = divide mode (3 steps)
  963.  * is.sval  = offset of IP into daughter's genome
  964.  * is.sval2 = eject genome from soup = 0, 1 = leave in soup
  965.  */
  966. void pdivide(ce)  /* give life to new cell by puting in queue */
  967. Pcells  ce;
  968. {   I32s  tval;
  969.  
  970.     is.iip = is.dib = 1;
  971.     if (is.eins->exec)
  972.         return ;
  973.     is.mode  = 2;  /* full division */
  974.     tval = ce->c.re[NUMREG] + flaw(ce);
  975.     is.sval  = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  976.     tval = ce->c.re[NUMREG + 1] + flaw(ce);
  977.     is.sval2 = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  978. /*  is.sval2 = mo(tval, 2); */
  979. }
  980.  
  981. #endif  /* INST == 2 */
  982.